#include "MemoryPool.h"

__thread MemoryPool::mem_node * MemoryPool::free_list[MemoryPool::BUCKETS] = { NULL };
__thread unsigned  MemoryPool::available_bytes = 0;

MemoryPool::MemoryPool()
{
}

inline unsigned MemoryPool::getIndex(unsigned  size )
{
	if ( size < MIN_SIZE )
		return 0;
	else
		return size - MIN_SIZE;
}

void * MemoryPool::allocate(unsigned size)
{
	if ( size > MAX_SIZE )
	{
		return ::operator new(size);
	}

	void * ret = NULL;
       	unsigned index = getIndex(size);
 
	if ( free_list[index] != NULL )
	{
	      	ret = free_list[index];
	      	free_list[index] = free_list[index]->next_free;
	      	available_bytes -= size;
	}
       	else
       	{
	      	ret = free_list[index] = (mem_node *)new char[size];
	       	mem_node * iterator = free_list[index];
	      	for ( unsigned i = 1; i < TRUNK_NUM; ++i )
	       	{
		     	iterator->next_free = (mem_node *)new char[size];
		     	iterator = iterator->next_free;
		}
	      	iterator->next_free = NULL;
	      	free_list[index] = free_list[index]->next_free;
	      	available_bytes += (TRUNK_NUM-1) * size;
	}
       	return ret;
}

void MemoryPool::deallocate(void * p, unsigned size )
{
       	if ( size>MAX_SIZE || available_bytes+size>MAXSIZE_MEMORY )
       	{
		::operator delete(p);
	}
	else
	{
		unsigned index = getIndex(size);
	      	mem_node * temp = (mem_node *)p;
	      	temp->next_free = free_list[index];
	      	free_list[index] = temp;
	     	available_bytes += size;
       	}
}

void * MemoryPool::operator new(unsigned size, void *p)
{
	return p;
}

void * MemoryPool::operator new(unsigned size)
{
	return allocate(size);
}

void MemoryPool::operator delete( void * p , unsigned size)
{
      	deallocate(p, size);
}

